package br.brpv.silvestrin.vendas.mainactivity;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.*;
import br.brpv.silvestrin.vendas.R;
import br.brpv.silvestrin.vendas.domain.AddedItem;
import br.brpv.silvestrin.vendas.domain.ItemCfg;
import br.brpv.silvestrin.vendas.domain.UnitOfMeasurement;
import br.brpv.silvestrin.vendas.listeners.ItemConvertUMListener;
import br.brpv.silvestrin.vendas.util.FormatString;
import br.brpv.silvestrin.vendas.util.ShowMessage;
import br.brpv.silvestrin.vendas.webservice.ServerConnection;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;


public class DialogAddItem implements ItemConvertUMListener {

    public enum Mode {ADD_ITEM, EDIT_ITEM}
    private enum DiscountType {PERCENT, VALUE}

    private Activity mActivity;

    private Dialog dialog;

    private EditText itemNameEdit;
    private EditText amountEdit;
    private EditText priceEdit;
    private EditText obsEdit;
    private EditText itemNameCfgEdit;
    private EditText stockEdit;
    private Spinner umEdit;
    private EditText vlrDiscountEdit;
    private ToggleButton discountTypeButton;
    private Button removeButton;
    private Button saveButton;
    private EditText vlrBrutoEdit;
    private EditText vlrLiqEdit;

    private NumberFormat valueFormat = new DecimalFormat("#0.00");
    private TextWatcher textWatcher;

    private ArrayAdapter<UnitOfMeasurement> unitOfMeasurementArrayAdapter;
    private AddItemInterface addItemInterface;

    private String companyId;

    private AddedItem newAddedItem;
    private AddedItem editingItem;
    private Mode mode;

    private boolean waitForStockUpdate;

    public DialogAddItem(Activity activity, AddItemInterface addItemInterface){
        this.mActivity = activity;

        dialog = new Dialog(mActivity);

        dialog.setOwnerActivity(mActivity);
        dialog.setContentView(R.layout.confirm_add_item);
        dialog.setCanceledOnTouchOutside(true);

        amountEdit = (EditText)dialog.findViewById(R.id.confirm_item_qtde);
        priceEdit = (EditText)dialog.findViewById(R.id.confirm_price_edit);
        itemNameCfgEdit = (EditText) dialog.findViewById(R.id.confirm_item_cfg_desc);
        stockEdit = (EditText)dialog.findViewById(R.id.confirm_stock_edit);
        umEdit = (Spinner)dialog.findViewById(R.id.confirm_u_m__spinner);
        vlrDiscountEdit = (EditText)dialog.findViewById(R.id.confirm_disc_value);
        discountTypeButton = (ToggleButton) dialog.findViewById(R.id.confirm_disc_type);
        removeButton = (Button)dialog.findViewById(R.id.confirm_delete_button);
        saveButton = (Button)dialog.findViewById(R.id.confirm_save_button);
        itemNameEdit = (EditText)dialog.findViewById(R.id.confirm_item_desc);
        obsEdit = (EditText)dialog.findViewById(R.id.confirm_obs_edit);

        vlrBrutoEdit = (EditText) dialog.findViewById(R.id.confirm_vlr_brt_edit);
        vlrLiqEdit = (EditText) dialog.findViewById(R.id.confirm_vlr_liq_edit);

        textWatcher = new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                setAddItemValues();
            }

            @Override
            public void afterTextChanged(Editable editable) {
            }
        };

        this.addItemInterface = addItemInterface;
    }

    public void showAddItem(String cid, ItemCfg object) {
        final ItemCfg itemCfg;
        this.companyId = cid;
        newAddedItem = null;
        editingItem = null;
        mode = Mode.ADD_ITEM;

        dialog.setTitle(R.string.add_item_to_order_title);
        itemCfg = (ItemCfg)object;

        if(amountEdit != null) amountEdit.setText("0");
        if(priceEdit != null) {
            priceEdit.setText("0.0");
            priceEdit.addTextChangedListener(textWatcher);
            priceEdit.setEnabled(false);
        }
        if(obsEdit != null) obsEdit.setText("");

        if(itemNameEdit != null) {
            itemNameEdit.setText(itemCfg.getDescTela());
            itemNameEdit.requestFocus();
            itemNameEdit.selectAll();
        }

        ServerConnection.getItemCfgStock(companyId, itemCfg.getvItcomid(), itemCfg.getCodItem(), this);

        if(itemNameCfgEdit != null) itemNameCfgEdit.setText(itemCfg.getDescColetor());
        if(stockEdit != null) {
            stockEdit.setText(itemCfg.getQtdeEstoque());
            stockEdit.setVisibility(View.VISIBLE);
        }
        if(umEdit != null) {
            umEdit.setEnabled(true);
            umEdit.setSelection(getUnitOfMeasurementById(itemCfg.getCodUnidadeMedida()));
        }
        if(amountEdit != null) {
            amountEdit.setEnabled(true);
            amountEdit.addTextChangedListener(textWatcher);
        }

        if(vlrDiscountEdit != null) {
            vlrDiscountEdit.addTextChangedListener(textWatcher);
            vlrDiscountEdit.setText("0.0");
        }

        if(discountTypeButton != null) discountTypeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                setAddItemValues();
            }
        });

        if(removeButton != null) removeButton.setVisibility(View.INVISIBLE);

        saveButton.setText(R.string.confirm_add_button_text);
        saveButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                newAddedItem = getAddedItemData(itemCfg);
                if(newAddedItem.getAmount() != 0 && newAddedItem.getPrice() != 0.0){
                    ServerConnection.itemConvertUM(companyId, newAddedItem, DialogAddItem.this);
                } else {
                    ShowMessage.alertDialog(mActivity, mActivity.getString(R.string.message_amount_price_zero));
                }
            }
        });

        dialog.show();
    }

    private int getUnitOfMeasurementById(String codUnidadeMedida) {
        if(unitOfMeasurementArrayAdapter != null){
            for(int i = 0; i < unitOfMeasurementArrayAdapter.getCount(); i++){
                if(unitOfMeasurementArrayAdapter.getItem(i).getId().equals(codUnidadeMedida)) return i;
            }
        }
        return 0;
    }

    public void showEditItem(String cId, AddedItem object){
        final AddedItem addedItem = object;

        newAddedItem = null;
        editingItem = addedItem;
        mode = Mode.EDIT_ITEM;

        this.companyId = cId;

        dialog.setTitle(R.string.edit_item_to_order_title);
        waitForStockUpdate = true;
        ServerConnection.getItemCfgStock(companyId, addedItem.getvItcomid(), addedItem.getCodItem(), this);

        if(amountEdit != null) amountEdit.setText(String.valueOf(addedItem.getAmount()));
        if(priceEdit != null){
            priceEdit.setEnabled(true);
            priceEdit.addTextChangedListener(textWatcher);
            priceEdit.setText(String.valueOf(addedItem.getPrice()));
        }
        if(obsEdit != null) obsEdit.setText(addedItem.getObs());

        itemNameEdit.setText(addedItem.getDescription());
        itemNameEdit.requestFocus();
        itemNameEdit.selectAll();


        if(itemNameCfgEdit != null) itemNameCfgEdit.setText(addedItem.getDescription());
        if(stockEdit != null) {
            stockEdit.setText(addedItem.getStock());
            stockEdit.setVisibility(View.VISIBLE);
        }
        if(umEdit != null){
            umEdit.setSelection(getUnitOfMeasurementById(addedItem.getUniMedidaId()));
            umEdit.setEnabled(true);
        }
        if(amountEdit != null) {
            amountEdit.addTextChangedListener(textWatcher);
        }

        if(vlrDiscountEdit != null) {
            vlrDiscountEdit.addTextChangedListener(textWatcher);
            vlrDiscountEdit.setText(String.valueOf(addedItem.getValueDiscount()));
        }

        if(discountTypeButton != null) discountTypeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                setAddItemValues();
            }
        });


        if(removeButton != null){
            removeButton.setVisibility(View.VISIBLE);
            removeButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    addItemInterface.removeItem(addedItem);
                    dialog.dismiss();
                }
            });
        }

        if(saveButton != null){
            saveButton.setText(R.string.confirm_save_button_text);
            saveButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if(waitForStockUpdate){
                        ShowMessage.alertDialog(mActivity, mActivity.getString(R.string.message_wait_stock_update));
                    } else {
                        newAddedItem = getAddedItemData(addedItem);
                        if(newAddedItem.getAmount() != 0 && newAddedItem.getPrice() != 0.0){
                            ServerConnection.itemConvertUM(companyId, newAddedItem, DialogAddItem.this);
                        } else {
                            ShowMessage.alertDialog(mActivity, mActivity.getString(R.string.message_amount_price_zero));
                        }
                    }

                }
            });
        }

        dialog.show();
    }

    private AddedItem getAddedItemData(Object object){
        ItemCfg itemCfg = null;
        AddedItem item = null;

        if(object.getClass() == AddedItem.class){
            item = (AddedItem)object;
        }else {
            itemCfg = (ItemCfg) object;
        }

        int amountVl = 0;
        String amountText = amountEdit.getText().toString();
        if(amountText.length() > 0) amountVl = new Integer(amountText);

        double priceVl = 0;
        String priceText = priceEdit.getText().toString();
        if(priceText.length() > 0) priceVl = new Double(priceText);

        String discountType;
        if(discountTypeButton.isChecked()) discountType = "V";
        else discountType = "P";

        String vlrDiscountText = vlrDiscountEdit.getText().toString();
        if(vlrDiscountText.length() == 0) vlrDiscountText = "0.0";
        double vlrDiscount = new Double(vlrDiscountText);

        String itemDescr = itemNameEdit.getText().toString();
        String obs = obsEdit.getText().toString();

        UnitOfMeasurement unitOfMeasurement = (UnitOfMeasurement)umEdit.getSelectedItem();

        AddedItem newAddedItem;
        if(item != null) {  //editing an existing item in order
            newAddedItem = new AddedItem(amountVl, priceVl,
                    obs, discountType, vlrDiscount, itemDescr, item.getCodItem(), item.getvItcomid(), unitOfMeasurement.getId(),
                    unitOfMeasurement.getShortName(), item.getStock(), item.isAllowNoStockSale());
        } else {          //adding a new item to order
            newAddedItem = new AddedItem(amountVl, priceVl,
                    obs, discountType, vlrDiscount, itemDescr, itemCfg.getCodItem(), itemCfg.getvItcomid(), unitOfMeasurement.getId(),
                    unitOfMeasurement.getShortName(), stockEdit.getText().toString(), itemCfg.isAllowNoStockSale());
        }

        return newAddedItem;
    }

    private void setAddItemValues(){

        DiscountType discountType;
        if(discountTypeButton.isChecked()) discountType = DiscountType.VALUE;
        else discountType = DiscountType.PERCENT;

        String amountText = amountEdit.getText().toString();
        String priceText = priceEdit.getText().toString();
        String discountText = vlrDiscountEdit.getText().toString();

        if(amountText.length() > 0 && priceText.length() > 0) {
            double amount = new Double(amountText);
            double price = new Double(priceText);
            double discount;
            if(discountText.length() > 0 ) discount = new Double(discountText);
            else discount = 0;

            vlrBrutoEdit.setText(calcValorBruto(amount, price));
            vlrLiqEdit.setText(calcValorLiquido(discountType, amount, price, discount));
        }
    }

    private String calcValorBruto(double amount, double price){
        double result = 0;

        result = amount * price;

        return FormatString.formatValue(result);
    }

    private String calcValorLiquido(DiscountType discountType,double amount, double price, double discount){
        double result = 0;

        switch (discountType){
            case PERCENT:
                result = amount * price * (100 - discount) / 100;
                break;
            case VALUE:
                result = amount * price - discount;
                break;
        }

        return FormatString.formatValue(result);
    }

    public void setItemPrice(double price){
        if(priceEdit != null) {
            priceEdit.setEnabled(true);
            priceEdit.setText(FormatString.formatValue(price));
        }
    }

    public void setUnitsOfMeasurement(ArrayList<UnitOfMeasurement> unitOfMeasurementArrayList) {
        unitOfMeasurementArrayAdapter = new ArrayAdapter<UnitOfMeasurement>(mActivity,
                R.layout.simple_spinner_item_custom, unitOfMeasurementArrayList);
        umEdit.setAdapter(unitOfMeasurementArrayAdapter);
    }

    @Override
    public Context getActivity() {
        return mActivity;
    }

    @Override
    public void failedOnGetConvertUMValue() {

    }

    @Override
    public void OnWebServiceConvertUMValueReturn(double resultValue) {
        double convertedAmount = resultValue * newAddedItem.getAmount();
        Toast.makeText(mActivity, convertedAmount + " unidades do estoque.", 10).show();
        newAddedItem.setAmountFromStock(convertedAmount);
        if(convertedAmount == 0) {
            ShowMessage.alertDialog(mActivity, mActivity.getString(R.string.message_invalid_unit_of_measurement));
        } else if(convertedAmount > Double.parseDouble(newAddedItem.getStock()) && !newAddedItem.isAllowNoStockSale()) {
            ShowMessage.alertDialog(mActivity, mActivity.getString(R.string.message_stock_insufficient));
        } else {
            if(mode == Mode.ADD_ITEM) addItemInterface.addItem(newAddedItem);
            else addItemInterface.saveItem(editingItem, newAddedItem);
            dialog.dismiss();
        }
    }

    @Override
    public void failedOnRetrieveStock() {
        waitForStockUpdate = false;
    }

    @Override
    public void OnWebServiceItemCfgStockReturn(String qtdeEstoque) {
        if(mode == Mode.EDIT_ITEM) {
            double stock = Double.parseDouble(qtdeEstoque);
            stock = stock + editingItem.getAmount();

            stockEdit.setText(String.valueOf(stock));
            editingItem.setStock(String.valueOf(stock));
        } else {
            stockEdit.setText(qtdeEstoque);
        }
        waitForStockUpdate = false;
    }
}
